<!DOCTYPE html>
<html lang="zh-CH" >
<head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="author" content="" />
	
	
	
	<title>基于HeadFirst设计模式之策略模式 ｜ zansimple</title>
	
    
    
    <meta name="description" content="最近在看一本书 HeadFirst 设计模式感觉还不错，下面会对这本书所涉及到的几种设计模式分析一下 下面书中所介绍的第一个设计模式 入门级的 策略模式 策略模式定义了算法族，分别封装起来，让他们之间可以相互替换，此模式让算法的变化独立于使用算法的客户 下面具体根据例子来讲解 （针对超类型编程） 模拟鸭子应用 1.鸭子 fly swim quack&amp;hellip; 首先根据鸭子的行为设计两个接口 FlyBehavior QuackBehavior
interface FlyBehavior{void Flying();}interface QuackBehavior{void Quacking();} 然后在设计对应的类，负责实现具体的行为
public class FlyWithWings:FlyBehavior{public void Flying(){print(&amp;quot;I&#39;m flying...&amp;quot;);}}public class FlyNoWay:FlyBehavior{public void Flying(){//什么都不做print(&amp;quot;I can not fly&amp;quot;);}}public class Quack:QuackBehavior{public void Quacking(){print(&amp;quot;鸭子呱呱叫...&amp;quot;);}}public class Squeak:QuackBehavior{public void Quacking(){print(&amp;quot;橡皮鸭子吱吱叫." />
    

    

	
    
    <link rel="shortcut icon" href="https://lenzan.github.io/images/favicon.ico" />

    <link rel="stylesheet" type="text/css" media="screen" href="https://lenzan.github.io/css/normalize.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://cdn.jsdelivr.net/npm/animate.css@4.1.0/animate.min.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://lenzan.github.io/css/zozo.css" />
	<link rel="stylesheet" type="text/css" media="screen" href="https://cdn.jsdelivr.net/npm/remixicon@2.5.0/fonts/remixicon.css" />
    <link rel="stylesheet" type="text/css" media="screen" href="https://lenzan.github.io/css/highlight.css" />

    
    
</head>

<body>
    <div class="main animate__animated animate__fadeInDown">
        <div class="nav_container animated fadeInDown">
    <div class="site_nav" id="site_nav">
        <ul>
            
            <li>
                <a href="/">首页</a>
            </li>
            
            <li>
                <a href="/">unity</a>
            </li>
            
            <li>
                <a href="/">归档</a>
            </li>
            
            <li>
                <a href="/">关于</a>
            </li>
            
        </ul>
    </div>
    <div class="menu_icon">
        <a id="menu_icon"><i class="ri-menu-line"></i></a>
    </div>
</div>
        <div class="header animated fadeInDown">
    <div class="site_title_container">
        <div class="site_title">
            <h1>
                <a href="https://lenzan.github.io/">
                    <span>zansimple</span>
                    <img src="https://lenzan.github.io/images/logo.svg" />
                </a>
            </h1>
        </div>
        <div class="description">
            <p class="sub_title">专注于Unity虚拟现实开发，游戏开发</p>
            <div class="my_socials">
                
                <a href="https://lenzan.github.io/index.xml" type="application/rss+xml" title="rss" target="_blank"><i
                        class="ri-rss-fill"></i></a>
            </div>
        </div>
    </div>
</div>
        <div class="content">
            <div class="post_page">
                <div class="post animate__animated animate__fadeInDown">
                    <div class="post_title post_detail_title">
                        <h2><a href='/posts/design/HeadFirst/'>基于HeadFirst设计模式之策略模式</a></h2>
                        <span class="date">2018.06.09</span>
                    </div>
                    <div class="post_content markdown"><p>最近在看一本书 HeadFirst 设计模式感觉还不错，下面会对这本书所涉及到的几种设计模式分析一下
下面书中所介绍的第一个设计模式 入门级的  策略模式
策略模式定义了算法族，分别封装起来，让他们之间可以相互替换，此模式让算法的变化独立于使用算法的客户
下面具体根据例子来讲解 （针对超类型编程）
模拟鸭子应用
1.鸭子 fly swim quack&hellip;
首先根据鸭子的行为设计两个接口 FlyBehavior  QuackBehavior</p>
<pre><code>interface FlyBehavior
{
    void Flying();
}
interface QuackBehavior
{
    void Quacking();
}
</code></pre>
<p>然后在设计对应的类，负责实现具体的行为</p>
<pre><code>public class FlyWithWings:FlyBehavior
{
    public void Flying()
    {
        print(&quot;I'm flying...&quot;);
    }
}
public class FlyNoWay:FlyBehavior
{
    public void Flying()
    {
        //什么都不做
        print(&quot;I can not fly&quot;);
    }
}
public class Quack:QuackBehavior
{
    public void Quacking()
    {
        print(&quot;鸭子呱呱叫...&quot;);
    }
}
public class Squeak:QuackBehavior
{
    public void Quacking()
    {
        print(&quot;橡皮鸭子吱吱叫...&quot;);
    }
}
public class MuteQuack:QuackBehavior
{
    public void Quacking()
    {
        //什么都不做
        print(&quot;不会叫...&quot;);
    }
}
</code></pre>
<p>这样的设计，可以让飞行和呱呱叫的动作被其他的对象复用，因为这些行为已经与鸭子没有关系了</p>
<p>而我们新增的一些行为，不会影响到既有的行为类，也不会影响“使用”到飞行类的鸭子类</p>
<p>我们整合一下鸭子的行为
关键在于，鸭子现在会将飞行和叫的动作委托别人处理，而不是定义在 Duck（或者子类）内的呱呱叫和飞行的方法
下面我们写一下超类 Duck</p>
<pre><code>public abstract class Duck
{
    //为行为接口类型声明两个引用变量，所有的鸭子类都继承他们
    public FlyBehavior flyBehavior;
    public QuackBehavior quackBehavior;
	
    public abstract void display();
	
    public void PerfromFly()
    {
        flyBehavior.Flying();
    }
    public void PerfromQuack()
    {
        quackBehavior.Quacking();
    }
	
}
</code></pre>
<p>我们来看一下如何设定 flyBehavior 和 quackBehavior 的实例变量</p>
<pre><code>public class MallardDuck:Duck
{
    public MallardDuck()
    {
        //使用 Quack 类处理呱呱叫，当 PerfromQuack() 被调用时叫的职责被委托给 Quack 对象，而我们得到了真正的呱呱叫
        quackBehavior=new Quack();
        //使用 FlyWithWings 作为其 FlyBehavior 类型
        flyBehavior=new FlyWithWings();
    }
	
    public void display()
    {
        print(&quot;I'm a real Mallard duck&quot;);
    }
}
</code></pre>
<p>编译测试类</p>
<pre><code>public class MiniDucks
{
    public static void Main(string[] arg)
    {
        Duck mallard =new MallardDuck();
        mallard.PerfromFly();//这个会调用 MallardDuck 继承来的 PerfromFly() 方法，进而委托给该对象的 FlyBehavior 对象处理
        mallard.PerfromQuack();
    }
}
</code></pre>
<p>动态设定行为
在鸭子里建立了一堆动态功能没有用到，就太可惜了！ 假设我们想在鸭子的子类中通过设定方法（set）来设定鸭子的行为
而不是在鸭子的构造器内实例化
在 Duck 类中加入两个新的方法</p>
<pre><code>public void SetFlyBehavior(FlyBehavior fb)
{
    flyBehavior=fb;
}
public void SetQuackBehavior(QuackBehavior qb)
{
    quackBehavior=qb;
}
</code></pre>
<p>以后我们可以随时调用这两个方法改变鸭子的行为。</p>
<p>添加一个新的鸭子类型</p>
<pre><code>public class ModelDuck:Duck
{
    public ModelDuck()
    {
        flyBehavior=new FlyNoWay();
        quackBehavior=new Quack();
    }
    public void display()
    {
        print(&quot;I'm a model duck&quot;);
    }
}
</code></pre>
<p>建立一个新的 FlyBehavior 类型</p>
<pre><code>public class FlyRocketPowered : FlyBehavior
{
    public void Flying()
    {
        print(&quot;I'm flying with rocket!&quot;);
    }
}
</code></pre>
<p>改变测试类</p>
<pre><code>public class MiniDucks
{
    public static void Main(string[] arg)
    {
        Duck model =new ModelDuck();
        model.PerfromFly();
        model.SetFlyBehavior(new FlyRocketPowered());
        model.PerfromFly();
    }
}
</code></pre>
<p>在运行时想改变鸭子的行为，只需要调用鸭子的Set方法就可以。</p>
<p>当你需要给朋友留下深刻的印象，或是想影响关键主管的决策时，请使用策略模式的定义</p>
<p>OK！ 策略模式到这里就结束了，这只是第一种模式，后面还会陆续更新其他的设计模式 敬请期待&hellip;</p>
</div>
                    <div class="post_footer">
                        
                        <div class="meta">
                            <div class="info">
                                <span class="field tags">
                                    <i class="ri-stack-line"></i>
                                    
                                    <a href="https://lenzan.github.io/tags/%E7%AD%96%E7%95%A5%E6%A8%A1%E5%BC%8F/">策略模式</a>
                                    
                                    <a href="https://lenzan.github.io/tags/%E8%AE%BE%E8%AE%A1%E6%A8%A1%E5%BC%8F/">设计模式</a>
                                    
                                </span>
                            </div>
                        </div>
                        
                    </div>
                </div>
                
                
            </div>
        </div>
    </div>
    <a id="back_to_top" href="#" class="back_to_top"><span>△</span></a>
    <footer class="footer">
    <div class="powered_by">
        <a href="https://varkai.com">Designed by VarKai,</a>
        <a href="http://www.gohugo.io/">Proudly published with Hugo</a>
    </div>

    <div class="footer_slogan">
        <span></span>
    </div>
</footer>
    <script src="https://lenzan.github.io/js/jquery-3.5.1.min.js"></script>
<link href="https://lenzan.github.io/css/fancybox.min.css" rel="stylesheet">
<script src="https://lenzan.github.io/js/fancybox.min.js"></script>
<script src="https://lenzan.github.io/js/zozo.js"></script>






</body>

</html>